package com.kvn.universal.core;

import java.util.List;

import com.google.common.collect.Lists;
import com.kvn.universal.filter.Filter;

/**
 * invoker 的执行链构造器
 * @author wzy
 * @date 2017年7月14日 下午12:26:07
 */
public abstract class InvokerBuilder {

	/**
	 * 构造 invoker 的执行链。按添加顺序，排在前面的 Filter 会优先执行，最后执行 业务逻辑 bizInvoker
	 * @param bizInvoker
	 * @param lockContext
	 * @param filters
	 * @return
	 */
	public static InvokerDelegate buildInvoker(final Invoker bizInvoker, InvokerContext lockContext, Filter... filters) {
		if (filters == null || filters.length == 0) {
			throw new RuntimeException("filters is empty");
		}
		return InvokerBuilder.buildInvoker(bizInvoker, lockContext, Lists.newArrayList(filters));
	}

	public static InvokerDelegate buildInvoker(final Invoker bizInvoker, InvokerContext lockContext, List<Filter> filterLs) {
		if (filterLs == null || filterLs.size() == 0) {
			throw new RuntimeException("filterLs is empty");
		}
		InvokerDelegate delegate = null;
		Invoker last = bizInvoker;
		for (int i = filterLs.size() - 1; i >= 0; i--) {
			final Filter filter = filterLs.get(i);
			final Invoker next = last;
			if (i == 0) {
				return new InvokerDelegate(lockContext) {
					@Override
					public Object invoke(InvokerContext lockContext) {
						return filter.invokeWapper(next, lockContext);
					}
				};
			}
			last = new Invoker() {
				@Override
				public Object invoke(InvokerContext lockContext) {
					return filter.invokeWapper(next, lockContext);
				}
			};
		}

		return delegate;
	}

}
